perm filename DISPLY.FAI[S,NET]4 blob
sn#845899 filedate 1987-09-11 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00025 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00005 00002 SUBTTL Display routines, intended to be .INSERTed history NLINES LINEL DMBUFL NCHARS NWRDLN SCRSIZ NGW DISLIN DMLIN DDDLIN TRUNCA NOEEOL NOEEOB
C00008 00003 Data area DPCBEG DDP IIIP DMP HSIZE VSIZE ROLLP VPOS HPOS OVPOS SLUPDP SCUPDP SAUPDP CRUPDP SCRLCT DMCNT DMPNT DPCEND
C00010 00004 Display commands and programs IIIHDR SDISP SCP SCREEN SCREND SCPL BOTLIN CDISP SCC SCCL LDISP LNP DMDISP DMPGM
C00012 00005 DPYINI -- Initialize display package DPYINI NOTIII
C00014 00006 CLRSCN -- Clear display screen (does explicit update as well) CLRSCN SCRIN1 DMCEOF
C00016 00007 SCSTOR -- Store a character at the current screen V/H position SCSTOR SCSTO2 SCBYTP
C00018 00008 CLREOL -- Clear to end of line CLREOL CLEOL0 CLEOL1
C00019 00009 CLREOF -- Clear to end of screen CLREOF CLEOF1
C00020 00010 CLR1CH -- Delete a character at the cursor CLR1CH CLR1C0
C00021 00011 CSRPOS -- position cursor CSRPOS
C00022 00012 TERPRI -- CR, LF, CLEOL, scroll if necessary TERPRI
C00023 00013 CARRET -- CR CARRET
C00024 00014 LINEFD -- LF, CLEOL, scroll if necessary LINEFD LINFD1
C00025 00015 LINSRV -- Line starve LINSRV LINSR1
C00026 00016 CSRTAB -- Tab cursor CSRTAB CSRTA0
C00027 00017 CSRAOS -- Forespace cursor CSRAOS CSRAO0
C00028 00018 CSRSOS -- Backspace cursor CSRSOS CSRSO0
C00029 00019 INSLIN -- Insert a blank line INSLIN INSLN0 INSL1A INSLN1 INSLN2
C00031 00020 DELLIN -- Delete a blank line DELLIN DELLN0 DELL1A DELLN1
C00033 00021 INSCHR -- Insert a blank character INSCHR INSCH0 INSC1A INSCH2 INSCH1
C00036 00022 DELCHR -- Delete a character DELCHR DELCH0 DELC1A DELCH2 DELCH1
C00039 00023 SCNUPD -- Update screen SCNUPD CSRUPD SCUPD1 SCUP1A SCUPD2
C00042 00024 GETCSY UDPLIN redisplay subroutines GETCSY UPDLIN
C00044 00025 DMCHAR DMOUT Datamedia output routines DMCHAR DMOUT
C00046 ENDMK
C⊗;
SUBTTL Display routines, intended to be .INSERTed ;⊗ history NLINES LINEL DMBUFL NCHARS NWRDLN SCRSIZ NGW DISLIN DMLIN DDDLIN TRUNCA NOEEOL NOEEOB
;This is a library of display hacking routines. Each routine documents its
;calling sequence and what AC's it smashes. Only AC's 0-6 are used. A
;pushdown stack is expected in 17.
;Original implementation by Mark Crispin, SU-AI, July 1978
COMMENT ⊗ History (please record changes):
26 Feb 84 JJW Conversion from MIDAS to FAIL.
28 May 86 ME Put in tests for HPOS overflowing buffers, to avoid clobbering
things outside SCREEN array with characters. Also, SCSTOR
fixed to wrap around automatically (with CR and LF) if attempt
to store character beyond right margin (HSIZE).
11 Sep 87 JJW Changed CAMGE 2,HSIZE to CAMG at SCSTOR+1 since HSIZE is one
less than the number of columns.
history: end of comment ⊗
BEGIN DISPLY
; Useful definitions
NLINES←←=40 ; lines in screen matrix
LINEL←←=88 ; true maximum number of characters/line
DMBUFL←←=100 ; size of DM buffer
NCHARS←←<<<LINEL+5>/5>*5> ; characters/line in line array
NWRDLN←←4+NCHARS/5 ; number of words in line array
SCRSIZ←←NLINES*NWRDLN ; number of words in screen matrix
NGW←←<<NCHARS*3>+=17>/=16 ; number of graphics words
; Line characteristics bits
DISLIN←←<400000,,0> ; III
DMLIN←← <040000,,0> ; DM
DDDLIN←←<020000,,0> ; DD
; DM UPGIOT flags
TRUNCA←←<040000,,0> ; truncate output lines to =80 characters
NOEEOL←←<020000,,0> ; suppress CEOL when moving to a line
NOEEOB←←<010000,,0> ; suppress CEOL on blank line
; Generate a Data Disc/III command
DEFINE DDCMD(O1,D1,O2,D2,O3,D3)<
BYTE (8)D1,D2,D3(3)O1,O2,O3,4
>;DEFINE
; Insert a command in a DM display program
DEFINE DMCMD(CH)<
MOVE DMCNT
CAIGE 10
PUSHJ 17,DMOUT
MOVEI 177
PUSHJ 17,DMCHAR
MOVEI CH
PUSHJ 17,DMCHAR
>;DEFINE
; Data area ;⊗ DPCBEG DDP IIIP DMP HSIZE VSIZE ROLLP VPOS HPOS OVPOS SLUPDP SCUPDP SAUPDP CRUPDP SCRLCT DMCNT DMPNT DPCEND
↑DPCBEG←←. ; beginning of core area zeroed at DPYINI
; Terminal characteristics
DDP: BLOCK 1 ; -1 → Data Disc
IIIP: BLOCK 1 ; -1 → III
DMP: BLOCK 1 ; -1 → Datamedia
↑HSIZE: BLOCK 1 ; horizontal size
↑VSIZE: BLOCK 1 ; vertical size
↑ROLLP: BLOCK 1 ; -1 → scrolling permission
; Cursor position pointers
VPOS: BLOCK 1 ; vertical position
HPOS: BLOCK 1 ; horizontal position
OVPOS: BLOCK 1 ; old vertical position
; Screen updating flags
SLUPDP: BLOCK NLINES ; -1 → this line has changed
SCUPDP: BLOCK 1 ; -1 → some update happened someplace
SAUPDP: BLOCK 1 ; -1 → updated whole screen
CRUPDP: BLOCK 1 ; -1 → updated cursor
SCRLCT: BLOCK 1 ; for forcing update in LINEFD scrolling
; DM display fields
DMCNT: BLOCK 1 ; DM program counter
DMPNT: BLOCK 1 ; DM program counter
DPCEND←←.-1 ; end of core data
; Display commands and programs ;⊗ IIIHDR SDISP SCP SCREEN SCREND SCPL BOTLIN CDISP SCC SCCL LDISP LNP DMDISP DMPGM
IIIHDR: BYTE (11)<-777>,640(3)4,2(2)1,2(4)6
SDISP: 600000,,SCP ↔ SCPL ↔ 0 ↔ SCP ; display screen
SCP: DDCMD 1,46,4,1,5,10
DDCMD 3,2,3,2,3,2
SCREEN: BLOCK SCRSIZ
SCREND←.-1
0
SCPL←←.-SCP
BOTLIN←←SCREEN+SCRSIZ-NWRDLN+2-1
CDISP: SCC ↔ SCCL ↔ 0 ↔ SCC+1 ; display cursor
SCC: DDCMD 1,7,1,7,1,7
DDCMD 3,1,4,0,5,0
BLOCK NGW
DDCMD 0,0,1,46,1,46
0
SCCL←←.-SCC
LDISP: 200000,,LNP ↔ NWRDLN ↔ 0 ↔ LNP ; display line
LNP: DDCMD 1,46,4,0,5,0
DDCMD 3,2,3,2,3,2
BLOCK NWRDLN-3
0
DMDISP: TRUNCA!NOEEOL!NOEEOB+DMPGM ↔ 0 ↔ 0; DM display program
DMPGM: BLOCK DMBUFL
; DPYINI -- Initialize display package ;⊗ DPYINI NOTIII
; Call: PUSHJ 17,DPYINI
; <return>
; Smashes 0.
↑DPYRDW:SETOM SAUPDP ;force text to be redrawn
SETOM CRUPDP ;force cursor to be redrawn
PPACT
LEYPOS 2000 ; flush page printer and line editor
POPJ 17,
↑DPYINI:SETZM DPCBEG
MOVE [DPCBEG,,DPCBEG+1]
BLT DPCEND ; initialize data area
HRROI [3000,,] ; real line chars
TTYSET ; get my line characteristics
TLNN (DISLIN!DDDLIN!DMLIN) ; display
JRST [ OUTSTR [ASCIZ/Not a display!/]
EXIT]
TLNE (DISLIN)
SETOM IIIP
TLNE (DDDLIN)
SETOM DDP
TLNE (DMLIN)
SETOM DMP
MOVE [-2,,[6000,,HSIZE ↔ 15000,,VSIZE]]
TTYSET ; get screen size information
MOVNI 2 ↔ ADDM VSIZE
SOS HSIZE
PPACT
LEYPOS 2000 ; flush page printer and line editor
MOVE VSIZE
MOVEM SCRLCT
SETOM ROLLP ; grant scrolling permission
SKIPN IIIP
JRST NOTIII
SETZM SCP ; different header for III's
MOVE IIIHDR
MOVEM SCP+1
NOTIII: SETOM OVPOS
SKIPN DMP
POPJ 17,
MOVEI <5*DMBUFL>-4
MOVEM DMCNT ; initialize DM counter
MOVE [440700,,DMPGM]
MOVEM DMPNT ; initialize DM pointer
POPJ 17,
; CLRSCN -- Clear display screen (does explicit update as well) ;⊗ CLRSCN SCRIN1 DMCEOF
; Call: PUSHJ 17,CLRSCN
; <return>
; Smashes 0, 1, 2, and 3.
↑CLRSCN:SETZM VPOS
SETZM HPOS
MOVE [<ASCII/ />+1]
MOVEM SCREEN
MOVE [SCREEN,,SCREEN+1]
BLT SCREND ; initialize screen to spaces
MOVE [<ASCII/
/>+1] ; terpri
SETZ 1, ; line address
DMOVE 2,[1 ↔ NLINES] ; blank word/line counter
SCRIN1: MOVEM 2,SCREEN(1)
MOVEM 2,SCREEN+1(1)
MOVEM SCREEN+NWRDLN-2(1)
MOVEM 2,SCREEN+NWRDLN-1(1)
ADDI 1,NWRDLN
SETZM SLUPDP-1(3) ; clear update necessary state for line
SOJG 3,SCRIN1
MOVEI 2
MOVEM SCC+2
MOVE [SCC+2,,SCC+3]
BLT SCC+2+NGW-1 ; initialize graphics words
SETOM SAUPDP ; updated entire screen
PUSHJ 17,SCNUPD
SKIPN DMP
POPJ 17,
DMCMD 14 ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
MOVE 1,VSIZE
DMCEOF: DMCMD 27 ; clear current line
DMCMD 15 ; move to next line
SOJG 1,DMCEOF
DMCMD 14 ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
JRST DMOUT
; SCSTOR -- Store a character at the current screen V/H position ;⊗ SCSTOR SCSTO2 SCBYTP
; Call: MOVE <character>
; PUSHJ 17,SCSTOR
; <return>
; Smashes 0, 1, 2, and 3.
↑SCSTOR:MOVE 2,HPOS
CAMG 2,HSIZE
JRST SCSTO2
PUSH 17,0 ; save char to be stored
PUSHJ 17,CARRET ; wrap around with CR
PUSHJ 17,LINEFD ; and LF
POP 17,0
MOVE 2,HPOS ; get new position
SCSTO2: MOVE 1,VPOS
SETOM SLUPDP(1) ; updated flags
SETOM SCUPDP
IMULI 1,NWRDLN
IDIVI 2,5 ; word position in line
ADDI 1,SCREEN+2(2) ; offset by lines previous
DPB 0,SCBYTP(3) ; save character on screen
AOS HPOS
SKIPE DMP
JRST DMCHAR
POPJ 17,
; Byte pointer table for insertions
SCBYTP: 350700,,(1)
260700,,(1)
170700,,(1)
100700,,(1)
010700,,(1)
; CLREOL -- Clear to end of line ;⊗ CLREOL CLEOL0 CLEOL1
; Call: PUSHJ 17,CLREOL
; <return>
; Smashes 0, 1, 2, 3, and 4.
↑CLREOL:SKIPN DMP
JRST CLEOL0
DMCMD 27 ; clear to end of line
CLEOL0: MOVE 4,HPOS
CAIL 4,LINEL
POPJ 17,
MOVE 1,VPOS
SETOM SLUPDP(1) ; flag this line changed
SETOM SCUPDP
IMULI 1,NWRDLN
MOVE 2,HPOS
IDIVI 2,5
ADDI 1,SCREEN+2(2) ; address of word to hack
MOVE 2,SCBYTP(3)
MOVEI " "
DPB 2 ; clear character
CLEOL1: ADDI 4,1 ; next character position
CAIL 4,LINEL
POPJ 17,
IDPB 2
JRST CLEOL1
; CLREOF -- Clear to end of screen ;⊗ CLREOF CLEOF1
; Call: PUSHJ 17,CLREOF
; <return>
; Smashes 0, 1, 2, 3, and 4.
↑CLREOF:PUSH 17,HPOS
PUSH 17,VPOS
CLEOF1: PUSHJ 17,CLREOL ; clear to end of line
DMCMD 15 ; next line
SETZM HPOS
AOS 1,VPOS
CAIGE 1,NLINES
JRST CLEOF1
POP 17,VPOS
POP 17,HPOS
DMCMD 14 ; cursor ← [0,2]
MOVEI 140
PUSHJ 17,DMCHAR
MOVEI 142
PUSHJ 17,DMCHAR
POPJ 17,
; CLR1CH -- Delete a character at the cursor ;⊗ CLR1CH CLR1C0
; Call: PUSHJ 17,CLR1CH
; <return>
; Smashes 0, 1, 2, and 3.
↑CLR1CH:SKIPN DMP
JRST CLR1C0
DMCMD " " ; space then backspace
DMCMD 10
CLR1C0: MOVEI " " ; store space at cursor
MOVE 1,VPOS
SETOM SLUPDP(1)
SETOM SCUPDP
IMULI 1,NWRDLN
MOVE 2,HPOS
CAIL 2,LINEL ; within valid range?
POPJ 17, ; no
IDIVI 2,5
ADDI 1,SCREEN+2(2)
DPB SCBYTP(3)
POPJ 17,
; CSRPOS -- position cursor ;⊗ CSRPOS
; Call: MOVE [xpos,,ypos]
; PUSHJ 17,CSRPOS
; <return>
; Smashes 0.
↑CSRPOS:HLRZM HPOS
HRRZM VPOS
SETOM CRUPDP
SKIPN DMP
POPJ 17,
DMCMD 14
MOVE HPOS
XORI 140
PUSHJ 17,DMCHAR
MOVE VPOS
ADDI 2
XORI 140
JRST DMCHAR
; TERPRI -- CR, LF, CLEOL, scroll if necessary ;⊗ TERPRI
; Call: PUSHJ 17,TERPRI
; <return>
; Smashes 0, 1, 2, 3, and 4.
↑TERPRI:PUSHJ 17,CARRET
PUSHJ 17,LINEFD
JRST CLREOL
; CARRET -- CR ;⊗ CARRET
; Call: PUSHJ 17,CARRET
; <return>
; Smashes 0.
↑CARRET:MOVE VPOS ; move to [0,current y]
JRST CSRPOS
; LINEFD -- LF, CLEOL, scroll if necessary ;⊗ LINEFD LINFD1
; Call: PUSHJ 17,CARRET
; <return>
; Smashes 0, 1, 2, 3, and 4.
↑LINEFD:AOS 1,VPOS ; and to next line
CAMGE 1,VSIZE
JRST LINFD1
SKIPN ROLLP
JRST [ SETZM VPOS ↔ JRST LINFD1]
MOVE [SCREEN+NWRDLN,,SCREEN]
BLT SCREEN+SCRSIZ-NWRDLN-1
MOVE [<ASCII/ />+1]
MOVEM BOTLIN+1
MOVE [BOTLIN+1,,BOTLIN+2]
BLT BOTLIN+<NCHARS/5>
SETOM SAUPDP
MOVE VSIZE ↔ SOS ↔ MOVEM VPOS
SOSG SCRLCT
PUSHJ 17,SCNUPD ; update after a screenfull of scrolling
LINFD1: SETOM CRUPDP
POPJ 17,
; LINSRV -- Line starve ;⊗ LINSRV LINSR1
; Call: PUSHJ 17,LINSRV
; <return>
; Smashes 0.
↑LINSRV:SKIPN DMP
JRST LINSR1
DMCMD 32
LINSR1: SOSGE VPOS
SETZM VPOS
SETOM CRUPDP
POPJ 17,
; CSRTAB -- Tab cursor ;⊗ CSRTAB CSRTA0
; Call: PUSHJ 17,CSRTAB
; <return>
; Smashes 0.
↑CSRTAB:SKIPE DMP
JRST CSRTA0
DMCMD 11 ; tab
CSRTA0: MOVE HPOS
TRZ 7
ADDI 10
MOVEM HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; CSRAOS -- Forespace cursor ;⊗ CSRAOS CSRAO0
; Call: PUSHJ 17,CSRAOS
; <return>
; Smashes 0.
↑CSRAOS:SKIPE DMP
JRST CSRAO0
DMCMD 34 ; forespace
CSRAO0: AOS HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; CSRSOS -- Backspace cursor ;⊗ CSRSOS CSRSO0
; Call: PUSHJ 17,CSRSOS
; <return>
; Smashes 0.
↑CSRSOS:SKIPE DMP
JRST CSRSO0
DMCMD 10 ; backspace
CSRSO0: SOSGE HPOS
SETZM HPOS
SETOM CRUPDP ; cursor updated
POPJ 17,
; INSLIN -- Insert a blank line ;⊗ INSLIN INSLN0 INSL1A INSLN1 INSLN2
; Call: MOVE <number of lines to insert>
; PUSHJ 17,INSLIN
; <return>
; Smashes 0, 1, 2, and 3.
↑INSLIN:PUSH 17, ; save argument
SKIPN DMP
JRST INSLN0
DMCMD 20 ; enter i/d mode on DM
INSLN0: SKIPN DMP
JRST INSL1A
DMCMD 12 ; insert a line on DM
INSL1A: MOVE 3,VPOS
IMULI 3,NWRDLN
ADDI 3,SCREEN ; address of first word of cursor line
CAIN 3,SCREEN+<NLINES-1>*NWRDLN ; skip unless at bottom line
JRST INSLN2
MOVE 1,[SCREEN+<NLINES-2>*NWRDLN,,SCREEN+<NLINES-1>*NWRDLN]
INSLN1: MOVE 2,1
BLT 2,NWRDLN-1(1) ; move line down
ADJSP 1,-NWRDLN
CAIE 3,(1)
JRST INSLN1
INSLN2: MOVE 1,[<ASCII/ />+1]
MOVEM 1,2(3)
MOVEI 1,NWRDLN-3(3)
ADDI 3,3
HRLI 3,-1(3)
BLT 3,(1)
SOSLE (17)
JRST INSLN0
ADJSP 17,-1 ; flush argument
SETOM SAUPDP
SKIPN DMP
POPJ 17,
DMCMD 30 ; leave i/d mode on DM
POPJ 17,
; DELLIN -- Delete a blank line ;⊗ DELLIN DELLN0 DELL1A DELLN1
; Call: MOVE <number of lines to delete>
; PUSHJ 17,DELLIN
; <return>
; Smashes 0, 1, 2, and 3.
↑DELLIN:PUSH 17, ; save argument
SKIPN DMP
JRST DELLN0
DMCMD 20 ; enter i/d mode on DM
DELLN0: SKIPN DMP
JRST DELL1A
DMCMD 32 ; delete a line on DM
DELL1A: MOVE 3,VPOS
IMULI 3,NWRDLN
ADDI 3,SCREEN ; address of first word of cursor line
CAIN 3,SCREEN+<NLINES-1>*NWRDLN ; skip unless at bottom line?
JRST DELLN1
MOVEI 1,(3)
ADDI 1,NWRDLN
HRLI 3,(1)
BLT 3,SCREEN+<NLINES-1>*NWRDLN-1; move the lines up
DELLN1: MOVE 1,[<ASCII/ />+1]
MOVEM 1,2(3)
MOVEI 1,NWRDLN-3(3)
ADDI 3,3
HRLI 3,-1(3)
BLT 3,(1)
SOSLE (17)
JRST DELLN0
ADJSP 17,-1 ; flush argument
SETOM SAUPDP
SKIPN DMP
POPJ 17,
DMCMD 30 ; leave i/d mode on DM
POPJ 17,
; INSCHR -- Insert a blank character ;⊗ INSCHR INSCH0 INSC1A INSCH2 INSCH1
; Call: MOVE <number of spaces to insert>
; PUSHJ 17,INSCHR
; <return>
; Smashes 0, 1, 2, 3, 4, 5, and 6.
↑INSCHR:PUSH 17, ; save count
SKIPN DMP ; is this a DM?
JRST INSCH0
DMCMD 20 ; yes, enter i/d mode
INSCH0: SKIPN DMP ; on a DM?
JRST INSC1A
DMCMD 34 ; insert a character
INSC1A: MOVE 1,VPOS ; get vertical position
IMULI 1,NWRDLN ; now number of words
MOVE 4,1 ; copy it for hacking
ADDI 4,SCREEN+NWRDLN-3 ; address of last text word
MOVE 2,HPOS ; get horizontal position
CAIL 2,LINEL ; within valid range?
JRST [ ADJSP 17,-1 ; no
POPJ 17,]
IDIVI 2,5 ; make it words
ADDI 1,SCREEN+2(2) ; address of word with cursor
LDB 2,[010700,,(1)] ; first character in next word
LDB 5,[ 103400,,(1)
102500,,(1)
101600,,(1)
100700,,(1)
100000,,(1)](3)
DPB 5,[ 013400,,(1)
012500,,(1)
011600,,(1)
010700,,(1)
010000,,(1)](3)
MOVEI 5," " ; space in hole
DPB 5,[ 350700,,(1)
260700,,(1)
170700,,(1)
100700,,(1)
010700,,(1)](3)
JRST INSCH1 ; check for being done
; At each iteration Y has last character, X has next address
INSCH2: MOVE 3,2 ; copy the character
LDB 2,[010700,,(1)] ; first character in next word
DPB 3,[000700,,(1)] ; last character here
MOVE 3,(1) ; get word being hacked
ROT 3,-7 ; put characters in right place
IORI 3,1 ; make sure bit 1.1 is on
MOVEM 3,(1) ; save character in word
INSCH1: CAME 1,4 ; at last address?
AOJA 1,INSCH2
SETOM SCUPDP ; some update somewhere
MOVE 1,VPOS ; this line
SOSLE (17)
JRST INSCH0 ; loop for more characters
ADJSP 17,-1
SETOM SLUPDP(1) ; this line was hacked
SKIPN DMP ; on a DM?
POPJ 17,
DMCMD 30 ; leave i/d mode
POPJ 17,
; DELCHR -- Delete a character ;⊗ DELCHR DELCH0 DELC1A DELCH2 DELCH1
; Call: MOVE <number of characters to delete>
; PUSHJ 17,INSCHR
; <return>
; Smashes 0, 1, 2, 3, 4, 5, and 6.
↑DELCHR:PUSH 17, ; save argument
SKIPN DMP ; is this a DM?
JRST DELCH0
DMCMD 20 ; yes, enter i/d mode
DELCH0: SKIPN DMP ; on a DM?
JRST DELC1A
DMCMD 10 ; delete a character
DELC1A: MOVE 1,VPOS ; get current vertical position
IMULI 1,NWRDLN ; number of words
MOVE 4,1 ; save it for later
ADDI 4,SCREEN+NWRDLN-3 ; address of last text word in line
MOVE 2,HPOS ; get horizontal position
CAIL 2,LINEL ; within valid range?
JRST [ ADJSP 17,-1 ; no
POPJ 17,]
IDIVI 2,5 ; number of words
ADDI 1,SCREEN+2(2) ; address of word with cursor
LDB 5,[ 013400,,(1)
012500,,(1)
011600,,(1)
010700,,(1)
010000,,(1)](3)
DPB 5,[ 103400,,(1)
102500,,(1)
101600,,(1)
100700,,(1)
100000,,(1)](3)
JRST DELCH1 ; check for being done
; Each time around the iteration A had address of next word
DELCH2: LDB 2,[350700,,(1)] ; last character in previous
DPB 2,[010700,,-1(1)] ; to previous
LDB 2,[013400,,(1)] ; get last characters in this word
DPB 2,[103400,,(1)] ; put back left justified
DELCH1: CAME 1,4 ; done?
AOJA 1,DELCH2
MOVEI 2," " ; get a space
DPB 2,[010700,,(1)] ; blank out last column
SETOM SCUPDP ; screen updated someplace
MOVE 1,VPOS ; get this line
SOSLE (17)
JRST DELCH0 ; hack another character
ADJSP 17,-1
SETOM SLUPDP(1) ; flag this line hacked
SKIPN DMP ; on a DM?
POPJ 17,
DMCMD 30 ; leave i/d mode
POPJ 17,
; SCNUPD -- Update screen ;⊗ SCNUPD CSRUPD SCUPD1 SCUP1A SCUPD2
; Call: PUSHJ 17,SCNUPD
; <return>
; Smashes 0, 1, 2, 3, and 4.
↑SCNUPD:MOVSI 1,-NLINES
SETZ 2,
SKIPE SLUPDP(1) ; does this line need hacking?
ADDI 2,1
AOBJN 1,.-2
SKIPN IIIP ; III always updates everything
CAIL 2,4 ; after four lines update entire screen
SETOM SAUPDP
MOVE VSIZE
MOVEM SCRLCT
AOSE SAUPDP ; update entire screen?
JRST SCUPD1
SETZM SCUPDP ; clear other update flags
SETZM SLUPDP
MOVE [SLUPDP,,SLUPDP+1]
BLT SLUPDP+NLINES-1
SKIPE DMP ; is this a DM?
JRST [ PUSHJ 17,DMOUT
JRST CSRUPD]
UPGIOT SDISP ; output new screen on DD and III
; Update cursor
CSRUPD: SKIPE DMP ; is this a DM?
JRST [ DMCMD 14 ; cursor ← [0,2]
MOVE HPOS
XORI 140
PUSHJ 17,DMCHAR
MOVE VPOS
ADDI 2
XORI 140
PUSHJ 17,DMCHAR
JRST DMOUT]
SKIPN DDP ; no cursor stuff yet for III's
POPJ 17,
MOVEI 2
MOVEM SCC+2
MOVE [SCC+2,,SCC+3]
BLT SCC+2+NGW-1 ; initialize graphics words
SKIPGE 1,OVPOS ; got an old position?
JRST .+3
PUSHJ 17,GETCSY ; get cursor vertical position
DDUPG CDISP ; clear cursor
MOVE 1,HPOS ; horizontal character position
CAIL 1,LINEL ; within valid range?
JRST [ SETOM OVPOS ; no, we won't have cursor now
POPJ 17,]
IMULI 1,6 ; horizontal bit position
ADDI 1,2 ; graphics mode hack
IDIVI 1,=32
MOVNS 2
MOVSI 3,740000
LSH 3,(2)
LDB 4,[010300,,3]
ROT 4,-3
TRZ 3,17
IORI 3,2
IORI 4,2
DMOVEM 3,SCC+2(1)
MOVE 1,VPOS ; save vertical position
MOVEM 1,OVPOS
PUSHJ 17,GETCSY
DDUPG CDISP ; draw new cursor
POPJ 17,
SCUPD1: AOSE SCUPDP ; did any update happen?
JRST SCUPD2
MOVSI 1,-NLINES
SCUP1A: SKIPE SLUPDP(1) ; need to hack this line?
PUSHJ 17,UPDLIN
AOBJN 1,SCUP1A
JRST CSRUPD
SCUPD2: AOSE CRUPDP ; was cursor hacked?
POPJ 17,
JRST CSRUPD
; GETCSY UDPLIN redisplay subroutines ;⊗ GETCSY UPDLIN
; Set up display program vertical position
GETCSY: IMULI 1,=12
ADDI 1,=24+=10
DPB 1,[140400,,SCC+1]
LSH 1,-4
DPB 1,[240500,,SCC+1]
POPJ 17,
; Display a single line
UPDLIN: SKIPE DMP
POPJ 17,
SKIPE LDISP+2
UPGIOT [0 ↔ 0 ↔ 0 ↔ 0] ; wait for previous
SETZM SLUPDP(1)
HRRZ 2,1 ; line number
IMULI 2,NWRDLN ; word position
MOVSI 2,SCREEN+2(2) ; address of start of line
HRRI 2,LNP+2
BLT 2,LNP+NWRDLN-2
HRRZ 2,1 ; get line number again
IMULI 2,=12
ADDI 2,=24 ; starting raster number
DPB 2,[140400,,LNP] ; zap in low 4 bits of address
LSH 2,-4 ; throw low bits away
DPB 2,[240500,,LNP] ; high 5 bits of address
UPGIOT LDISP ; display the line
POPJ 17,
; DMCHAR DMOUT Datamedia output routines ;⊗ DMCHAR DMOUT
; Character output to DM
DMCHAR: SOSG DMCNT ; any room in buffer?
PUSHJ 17,DMOUT
IDPB DMPNT ; save character
POPJ 17,
; Buffer output to DM; called when DM buffer full or want to force buffer out
↑DMOUT: SKIPN DMPGM ; any program there?
POPJ 17,
HRRZ DMPNT ; get current value of pointer
SUBI DMPGM-1 ; compute number of words used
MOVEM DMDISP+1 ; set number of words to do
UPGIOT DMDISP ; output DM program
MOVS HPOS
HRR VPOS
ADDI 2-1 ; two lines for who line
CURSOR ; bop the cursor to last position
SETZM DMPGM
MOVE [DMPGM,,DMPGM+1]
BLT DMPGM+DMBUFL-1 ; clear the old program
MOVEI <5*DMBUFL>-4
MOVEM DMCNT ; initialize DM counter
MOVE [440700,,DMPGM]
MOVEM DMPNT ; initialize DM pointer
MOVEI 177 ; quote
IDPB DMPNT
MOVEI 14 ; cursor position
IDPB DMPNT
MOVE HPOS ; horizontal position
XORI 140
IDPB DMPNT
MOVE VPOS ; vertical position
ADDI 2 ; who line space
XORI 140
IDPB DMPNT
POPJ 17,
BEND DISPLY